#include <iostream>

using std::cout;
using std::endl;

class Singleton
{
public:
    //只有第一次调用getInstance函数时，才执行new表达式
    //之后的调用都直接返回第一次调用的对象
    //将getInstance函数设计为static的原因是调用它时还没有生成对象
    //而只有静态成员函数不需要通过对象调用，可以直接使用类名调用
    static Singleton * getInstance()
    {
        if(_pInstance == nullptr) {
            _pInstance = new Singleton;
        }
        return _pInstance;
    }

    //设计成静态的，是为了与getInstance函数对应
    static void destroy()
    {
        if(_pInstance) {
            delete _pInstance;
            _pInstance = nullptr;
        }
    }

    void print() const
    {
        cout << "(" << _ix
             << "," << _iy
             << ")" << endl;
    }

    void init(int ix, int iy)
    {
        _ix = ix;
        _iy = iy;
    }

private:
    Singleton()
    : _ix(0), _iy(0)
    {   cout << "Singleton()" << endl;  }

    //禁止复制的写法：
    //1. 在C++11标准之前，将拷贝构造函数私有化
    //Singleton(const Singleton &);
    //2. 在C++11之后，可以直接从类中删除该函数delete
    Singleton(const Singleton &) = delete;

public:
    ~Singleton() {   cout << "~Singleton()" << endl;  }

private:
    //_pInstance设计为静态的，是因为静态成员函数之中只能访问静态数据成员
    static Singleton * _pInstance;
    int _ix;
    int _iy;
};

Singleton * Singleton::_pInstance = nullptr;

//static Singleton s1;//error
//static Singleton s2;

int main()
{
    //Singleton s3, s4;//error
    Singleton * p1 = Singleton::getInstance();
    Singleton * p2 = Singleton::getInstance();
    cout << "p1: " << p1 << endl;
    cout << "p2: " << p2 << endl;
    /* p1->init(10, 11); */
    /* p1->print(); */
    Singleton::getInstance()->init(10, 11);//实际操作时的用法
    Singleton::getInstance()->print();
    cout << endl;

    //拷贝构造
    //Singleton s2 = *Singleton::getInstance();//error
    //Singleton s2 = *p1;
    //s2.init(20,22);
    //s2.print();


    //delete p1;//不优雅error
    Singleton::destroy();

    return 0;
}

